/**
 * LGPL
 * @Author jw12
 */
package org.biodas.jdas.creators.writers;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;


import org.biodas.jdas.exceptions.DASClientException;
import org.biodas.jdas.schema.sources.SOURCES;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.AnnotationIntrospector;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.xc.JaxbAnnotationIntrospector;


/**
 * Class for writing Sources to xml or json LPGL
 * 
 * @author JWarren
 * 
 */
public class SourcesWriter {

	public void writeSourcesXmlToStandardOut(SOURCES sources)
			throws DASClientException {
		
			this.writeSourcesXmlToOutputStream(sources, System.out);
		
	}

	public void writeSourcesXmlToFile(SOURCES sources,
			String pathAndName) throws FileNotFoundException,
			DASClientException {

		OutputStream os = null;

		os = new FileOutputStream(pathAndName);

		this.writeSourcesXmlToOutputStream(sources, os);

	}

	/**
	 * @param dasGffAdapter
	 * @param pathAndName
	 */
	public void writeSourcesJsonToOutputStream(SOURCES sources,
			OutputStream out) throws FileNotFoundException, DASClientException {

//		AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
//		AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
//		AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary,
//				secondary);

		ObjectMapper mapper = new ObjectMapper();
	    //AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
	    AnnotationIntrospector primary = new JacksonAnnotationIntrospector();
    AnnotationIntrospector secondary = new JaxbAnnotationIntrospector();
    AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary);
	    // make deserializer use JAXB annotations (only)
	    mapper.setAnnotationIntrospector(pair);
            
            
	  
	    // make serializer use JAXB annotations (only)
	    //mapper.getSerializationConfig().setAnnotationIntrospector(introspector);
		mapper.configure(
				DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		mapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE,
				true);
//                mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT,
//				true);
                mapper.configure(SerializationConfig.Feature.WRITE_NULL_PROPERTIES,
				false);
		mapper.configure(SerializationConfig.Feature.WRITE_EMPTY_JSON_ARRAYS,
				false);
		mapper.configure(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES,
				false);

		// mapper.configure(f, state)
		try {
			mapper.writeValue(out, sources);

		} catch (JsonGenerationException e) {
		
			e.printStackTrace();
		} catch (JsonMappingException e) {
		
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		}

	}

	/**
	 * @param converted
	 */
	public void writeSourcesJsonToStandardOut(SOURCES sources)
			throws DASClientException {

		try {
			this.writeSourcesJsonToOutputStream(sources, System.out);
		} catch (FileNotFoundException e) {
			// won't get thrown as we are writing to stdout
			e.printStackTrace();
		}
	}

	public void writeSourcesXmlToOutputStream(SOURCES sources,
			OutputStream out) throws DASClientException {
		JAXBContext jc = null;
		try {
			jc = JAXBContext.newInstance("org.biodas.jdas.schema.sources");
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		Marshaller m = null;
		try {
			m = jc.createMarshaller();
		} catch (JAXBException e) {
			throw new DASClientException(e.getMessage(), e.getCause());
		}

		try {
			m.marshal(sources, out);
		} catch (JAXBException e) {
			throw new DASClientException(e.getMessage(), e.getCause());
		}

	}

	public void writeSourcesJsonToFile(SOURCES sources,
			String pathAndName) throws DASClientException,
			FileNotFoundException {
		OutputStream os = null;

		os = new FileOutputStream(pathAndName);

		try {
			this.writeSourcesJsonToOutputStream(sources, os);
		} catch (FileNotFoundException e) {
			// won't get thrown as we are writing to stdout
			e.printStackTrace();
		}
	}
}
